
module PrismBreak {

    export class ConfigManager {

        public ConfigItems: ConfigItem[];
        public ViewModels: { [key: string]: PbViewModel };

        private frameworkApp: PbApp;
        private viewModelToLoad: number;
        public loadingViewModelCompleted: boolean;

        constructor(frameworkApp: PbApp, configPath?: string) {

            this.frameworkApp = frameworkApp;

            this.ViewModels = {}; if (configPath) {
                this.LoadConfigItem(configPath);
            }

            if (this.ConfigItems.length) {
                this.LoadViewModels();
            }

        }

        public LoadConfigItem(path: string) {

            var cfgItem: ConfigItem;
            var cfgCollection: ConfigItem[] = [];


            $.ajax({
                async: false,
                global: false,
                url: path,
                dataType: "json",
                success: (data: Object) => {

                    $.each((<any>data).modules, (index: number, value: Object) => {

                        cfgItem = new ConfigItem();
                        cfgItem.JsonToConfigItem(value);
                        cfgCollection.push(cfgItem);
                    });

                    this.ConfigItems = cfgCollection;
                },
                error: () => {
                    console.log("error");

                }
            });
        }

        public LoadViewModels(): void {

            //shallow clone
            var jsonModules = this.ConfigItems.slice(0);
            var that = this;

            this.viewModelToLoad = jsonModules.length;

            for (var i = 0; i < jsonModules.length; i++) {

                if (jsonModules[i].ViewModelPath && jsonModules[i].ViewModelType) {

                    //Instantiate viewmodel and attach it to the region
                    this.LoadViewModelFromFS(jsonModules[i].ViewModelPath,
                        jsonModules[i].ViewModelType,
                        jsonModules[i].ReturnViewModelTypeArray(),
                        true,
                        (function (type) {
                            return function (script) {
                                that.CreateViewModel(script, type);
                            };
                        })(jsonModules[i].ViewModelType)
                        );

                }
            }
        }

        private LoadViewModelFromFS(path: string, viewModelType: string, viewModelTypeArray: string[], isAsync: boolean, callback?: Function): Function {

            var script: Function;

            $.ajax({
                async: isAsync,
                global: false,
                crossDomain: true,
                url: path,
                dataType: "script",
                success: (data: any) => {

                    var scope = <any>window;
                    for (var i = 0; i < viewModelTypeArray.length; i++) {
                        scope = scope[viewModelTypeArray[i]];
                    }

                    script = <Function>scope;

                    if (callback) {
                        callback(script);
                    }
                },
                error: () => {
                    console.log("error");
                }
            });

            return script;

        }

        private CreateViewModel(script: any, viewModelType: string): void {
            //instantiate

            var viewModel: PbViewModel = new script(this.frameworkApp);
            this.ViewModels[viewModelType] = viewModel;

            this.viewModelToLoad--;

            if (!this.viewModelToLoad) {
                this.loadingViewModelCompleted = true;
                this.frameworkApp.EventManager.Publish(PrismBreak.EventType[PrismBreak.EventType.ViewModelsAreLoaded]);
            }
        }
    }
}